package concurrent.sincalculator;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.StyledEditorKit;

/**
 *
 * @author harker777
 */
public strictfp class Master {

	private static final Integer MEMBERS_NUMBER = 1000;
	private static final Integer THREADS_NUMBER = 10;

	public static void main(String[] args) {
		// Distribute tasks (-MEMBRES_NUMBER to MEMBERS_NUMBER) evenly using TaskDistributor
		TaskDistributor taskDistributor = new TaskDistributorImpl();
		taskDistributor.distributeTasks(THREADS_NUMBER, -MEMBERS_NUMBER, MEMBERS_NUMBER);
		Integer[] froms = taskDistributor.getFroms();
		Integer[] tos = taskDistributor.getTos();
		
		// Spawn the slaves and start them
		ValueReturningRunnable<Double>[] runnables = new Slave[THREADS_NUMBER];
		Thread[] threads = new Thread[THREADS_NUMBER];
		for (int i = 0; i < THREADS_NUMBER; i++) {
			runnables[i] = new Slave(froms[i], tos[i]);
			threads[i] = new Thread(runnables[i]);
			threads[i].start();
		}
		
		// Wait for all slaves to finish
		waitForThreads(threads);
		
		// And sum all results (from slaves) for final result =)
		Double result = sumTheResults(runnables);
		System.out.println(result);
	}

	public static void printData(Integer[] data) {
		for (Integer value : data) {
			System.out.print(value + " ");
		}
		System.out.print("\n");
	}

	private static void waitForThreads(Thread[] threads) {
		// Wait for all slaves to finish their job
		for (int i = 0; i < THREADS_NUMBER; i++) {
			try {
				threads[i].join();
			} catch (InterruptedException ex) {
				System.out.println("Interrupted. Please try restarting.");
			}
		}
	}

	private static double sumTheResults(ValueReturningRunnable<Double>[] runnables) {
		// And well, compute the results of each slave
		double result = 0.0;
		for (int i = 0; i < THREADS_NUMBER; i++) {
			result += runnables[i].getValue();
		}
		return result;
	}
}
